#ifndef CENTITY_H_INCLUDED
#define CENTITY_H_INCLUDED

#include <map>
#include <sstream>
#include <vector>

#include <libtcod/libtcod.hpp>

#include "CAIModule.h"
#include "CGameObject.h"
#include "CItem.h"
#include "CTurnSchedule.h"

typedef enum
{
    ERS_DIMINUTIVE,
    ERS_TINY,
    ERS_SMALL,
    ERS_MEDIUM,
    ERS_LARGE,
    ERS_HUGE
} ERaceSize;

struct SRace
{
    char Key;
    char Shape;
    ERaceSize Size;
    unsigned int Speed;
    unsigned int Sight;
    TCOD_dice_t HitDie;
    TCOD_dice_t UnarmedDie;
};

class CEntity : public ITurnTaker, public CGameObject
{
public:
	CEntity(std::string name = "");
	virtual ~CEntity();

	virtual bool canSeePlayer();
	virtual bool isDead();

	virtual float getSkill(std::string key);

	virtual int getAttribute(std::string key);
	virtual int getCurrentFloor();
	virtual int getHealth();
	virtual int getLevel();
	virtual int getMaxHealth();
	virtual int getSight();
	virtual int getSpeed();

	static std::map<std::string, SRace> Races;

	virtual std::string getRace();

	virtual int attack(CEntity* target);

	virtual void damage(int damage);
	virtual void init(std::string race);
	virtual void setAttribute(std::string key, int value);
	virtual void setLevel(int level);
	virtual void setRace(std::string race);
	virtual void setSkill(std::string key, float value);
	void takeTurn();

	static void loadRaces();

protected:
	struct SEquipmentSlot
	{
		bool Occupied;
		char Key;
		CItem* Item;
	};

	bool Dead;

	char CurrentInventory;

	int CurrentFloor;
	int Health;
	int Level;
	int MaxHealth;
	int TicksSinceCombat;

	pair LastPosition;

	std::map<char, CItem*> Inventory;
	std::map<EEquipSlot, SEquipmentSlot> EquipSlots;
	std::map<std::string, float> Skills;
	std::map<std::string, int> Attributes;
	std::string Race;

private:
	bool CanSeePlayer;

	CAIModule* Module;
};

#endif
